/*
 * @Author: wangming
 * @Date: 2021-03-26 10:55:31
 * @LastEditors: wangming
 * @LastEditTime: 2022-07-18 18:11:37
 * @Description: file content
 */
const presetjsx = require("@vue/babel-preset-jsx");
import { session } from "store2";
import { transform as babelTransform } from "@babel/standalone";
import { Message } from 'element-ui'
import memoize from "memoize-one";
/**
 *   字符串转render函数
 * @param {*} jsx 
 * @returns 
 */
function FunForJSON(str, funName) {
  try {
    var fun = babelTransform(decodeURIComponent(str), {
      presets: ['env', presetjsx],
    }).code.replace('function', 'async function')
    return new Function(fun + `; return ${funName}`)()
  } catch (error) {
    console.log(error)
  }
}
export const getFunForJSON = memoize(FunForJSON)
/**
 *  jsx 字符串转render函数
 * @param {*} jsx 
 * @returns 
 */
function RenderFun(jsx) {
  if (!jsx) {
    Message.warning('模版函数不能为空')
    return
  }
  try {
    var fun = babelTransform('export ' + decodeURIComponent(jsx), {
      presets: ['env', presetjsx],
    }).code
    const exports = {}
    new Function('exports', fun)(exports)
    return exports.render
  } catch (error) {
    console.log(error)
  }
}
export const getRenderFun = memoize(RenderFun)
/**
 *  vue 模版渲染
 * 
 * @param {*} jsx 
 * @returns 
 */
function VueComponent(jsx) {
  if (!jsx) {
    Message.warning('模版函数不能为空')
    return
  }
  let jsStr = decodeURIComponent(jsx)
  var fun = jsStr.match(/export default[\s\S]+/)
  if (!!fun) {//兼容处理
    fun = String(fun)
    //await 自动添加async
    if (fun.startsWith('export default function') && fun.indexOf('await') > -1) {
      fun = fun.replace('export default function', 'export default async function')
    }
  } else {
    fun = jsStr.match(/const vueComponent[\s\S]+/) + '\nexport default vueComponent'
  }
  fun = babelTransform(fun, {
    presets: ['env', presetjsx],
  }).code
  const exports = {}
  new Function('exports', fun)(exports)
  return exports.default
}
export const getVueComponent = memoize(VueComponent)
/**
 * 生成自定义随机key
 * @param {*} len 
 * @param {*} radix 
 * @param {*} containTime 
 * @returns 
 */
export function uuid(len, radix, containTime) {
  var now = new Date();
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(
    ''
  );
  var uuid = [];
  var i;
  radix = radix || chars.length;
  if (len) {
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
  } else {
    var r;
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16);
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  if (containTime == null && containTime == true) {
    return now.getTime() + '' + uuid.join('');
  } else return uuid.join('');
}

export function getBase64ByImg(img, callback) {
  const reader = new FileReader();
  reader.addEventListener('load', () => callback(reader.result));
  reader.readAsDataURL(img);
}

/**
 * 数字转大写
 * @param {*} n 
 * @returns 
 */
export function SectionToChinese(n) {
  if (n === 0 || n === '0') {
    return '零元整';
  }
  if (!/^\d*(\.\d*)?$/.test(n) || !n) {
    return '-';
  }
  if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) {
    return '数据非法'; //判断数据是否大于0
  }
  var unit = '仟佰拾亿仟佰拾万仟佰拾元角分',
    str = '';
  n += '00';

  var indexpoint = n.indexOf('.'); // 如果是小数，截取小数点前面的位数

  if (indexpoint >= 0) {
    n = n.substring(0, indexpoint) + n.substr(indexpoint + 1, 2); // 若为小数，截取需要使用的unit单位
  }

  unit = unit.substr(unit.length - n.length); // 若为整数，截取需要使用的unit单位
  for (var i = 0; i < n.length; i++) {
    str += '零壹贰叁肆伍陆柒捌玖'.charAt(n.charAt(i)) + unit.charAt(i); //遍历转化为大写的数字
  }
  return str
    .replace(/零(仟|佰|拾|角)/g, '零')
    .replace(/(零)+/g, '零')
    .replace(/零(万|亿|元)/g, '$1')
    .replace(/(亿)万|壹(拾)/g, '$1$2')
    .replace(/^元零?|零分/g, '')
    .replace(/元$/g, '元整')
    .replace(/^拾/g, '壹拾')
    .replace(/([^壹,贰,叁,肆,伍,陆,柒,捌,玖])(拾)/g, '$1壹$2')
    .replace(/([^壹,贰,叁,肆,伍,陆,柒,捌,玖]元)([^整|^零])/g, '$1零$2'); // 替换掉数字里面的零字符，得到结果
}
/**
 * @description  递归过滤router tree
 * @author wangming
 * @date 2021-04-14
 * @export
 * @param {*} treeList
 * @param {*} fun  过滤条件
 * @returns
 */
export function transformRouter(treeList, fun) {
  return treeList.filter(fun).map((i) => {
    let children = [];
    if (!!i?.children?.length) {
      children = transformRouter(i.children, fun);
    }
    return Object.assign({}, i, { children });
  });
}
/**
 * tree获取平级对组件对象集合 非递归广度优先 ，获取最底层组件，排除布局组件
 * @param {*} tree formlist
 * tagNames 个别组件排除
 */
export function transformModelTree(tree, tagNames = []) {
  let queen = [];
  let out = [];
  queen = queen.concat(tree);
  while (queen.length) {
    let first = queen.shift();
    if (first.children && tagNames.indexOf(first.tagName) === -1) {
      queen = [].concat(first.children, queen);
    } else {
      if (typeof fun === 'function') {
        out.push(fun(first));
      } else {
        out.push(first);
      }
    }
  }
  return out;
}
/**
 * 
 * @param {*} tree 被处理的tree
 * @param {*} filterRule 过滤规则
 * @param {*} mapFun  返回结构
 * @returns 
 */
export function transformTreeFormRule(tree, filterRule, mapFun) {
  let queen = [];
  let out = [];
  queen = queen.concat(tree);
  while (queen.length) {
    let first = queen.shift();
    if (first.children) {
      queen = [].concat(first.children, queen);
    }
    if (filterRule(first)) {
      if (typeof mapFun === 'function') {
        out.push(mapFun(first));
      } else {
        out.push(first);
      }
    }
  }
  return out;
}
//表格表单权限逻辑
export const AuthFieldsFormList = class {
  static getBlackList(modelCode) {
    let fields = session.get("APP_fields") || [];
    let { fieldBlackList } =
      fields.find((i) => i.modelCode === modelCode) || {};
    return fieldBlackList
  }
  static transformAuthForForm(children, modelCode) {
    let fieldBlackList = this.getBlackList(modelCode)
    if (fieldBlackList?.length > 0) {
      this.fieldsFormListdeep(children, fieldBlackList);
    }
  }
  static fieldsFormListdeep(children, fieldBlackList) {
    children.forEach((i) => {
      if (fieldBlackList.indexOf(i.modelName) > -1) {
        i.key = null;
      } else if (i?.children?.length > 0 && !i.modelName) {
        this.fieldsFormListdeep(i?.children, fieldBlackList);
      }
    });
  }
  static transformAuthForTable(children, modelCode, key) {
    let fieldBlackList = this.getBlackList(modelCode)
    if (fieldBlackList?.length > 0) {
      children.forEach(i => {
        if (fieldBlackList.indexOf(i.code.replace(/_search$/, '')) > -1) {
          i[key] = false
        }
      })
    }
    return children.filter(i => i[key])
  }
  static transformAuthForSearch(children, modelCode) {
    let fieldBlackList = this.getBlackList(modelCode)
    if (fieldBlackList?.length > 0) {
      return children.filter(i => fieldBlackList.indexOf(i.modelName) === -1)
    } else {
      return children
    }
  }
}


